package com.guan.study.easyExcelDemo.utils;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;

/**
 * @Date: 2023/7/19 19:35
 * @Author: yaobai
 * @Description: excel自定义合并行
 */
public class CustomMergeColumn implements CellWriteHandler {

    //指定可以合并的列
    private final List<String> megerColumns;

    public CustomMergeColumn(List<String> megerColumns) {
        this.megerColumns = megerColumns;
    }

    /**
     * @date: 2023/7/21 9:47
     * @author: yaobai
     * @description: 在单元格上所有的操作完成后执行
     **/
    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
                                 List<WriteCellData<?>> cellDataList, Cell cell, Head head,
                                 Integer relativeRowIndex, Boolean isHead) {
        //跳过表头
        if (isHead){
            return;
        }
        //relativeRowIndex 表示数据行的索引，即第一行不存在合并的情况，直接过
        if (relativeRowIndex == 0){
            return;
        }
        //如果当前表头不是规定要合并的列 就跳过
        if (!this.megerColumns.contains(head.getFieldName())){
            return;
        }

        Sheet sheet = cell.getSheet();
        //当前行坐标
        int currentRowIndex = cell.getRowIndex();
        //上一行坐标
        int preRowIndex = currentRowIndex - 1;
        //上一行
        Row preRow = sheet.getRow(preRowIndex);
        //上一个单元格
        Cell preCell = preRow.getCell(cell.getColumnIndex());
        //当前单元格值
        String currentCellValue = "";
        
        if (cell.getCellType() == CellType.STRING){
            currentCellValue = cell.getStringCellValue();
        } else if (cell.getCellType() == CellType.NUMERIC) {
            currentCellValue = String.valueOf(cell.getDateCellValue());
        }
        //当前列上一行单元格值
        String preCellValue = "";

        if (preCell.getCellType() == CellType.STRING){
            preCellValue = preCell.getStringCellValue();
        } else if (preCell.getCellType() == CellType.NUMERIC) {
            preCellValue = String.valueOf(preCell.getDateCellValue());
        }

        //如果上下单元格值不相等，就返回
        if (!currentCellValue.trim().equals(preCellValue.trim())){
            return;
        }
        //标志：当前单元格是否存在于合并区域
        boolean merge = false;
        //获取到当前 Sheet 中所有已合并的单元格区域，并将其保存在一个名为 mergedRegion 的 List 对象中
        List<CellRangeAddress> mergedRegion = sheet.getMergedRegions();
        for (int i = 0; i < mergedRegion.size(); i++) {
            //当前合并区域
            CellRangeAddress addr = mergedRegion.get(i);
            //如果当前列的上一行单元格在该合并区域，
            if (addr.isInRange(preRowIndex,cell.getColumnIndex())){
                //删除该合并区域
                sheet.removeMergedRegion(i);
                //重新设置合并区域的最后一行为当前行
                addr.setLastRow(currentRowIndex);
                //重新添加合并区域
                sheet.addMergedRegion(addr);
                //打个标记，当前单元格存在合并区域里
                merge = true;

                break;
            }
        }

        //如果当前单元格不存在于任何合并区域
        if (!merge){
            //新建合并区域对象，设置坐标
            CellRangeAddress addresses =
                    new CellRangeAddress(preRowIndex,currentRowIndex,cell.getColumnIndex(),cell.getColumnIndex());
            //添加合并
            sheet.addMergedRegion(addresses);

        }

    }

    /**
     * @date: 2023/7/21 9:42
     * @author: yaobai
     * @description: 在单元格创建之前执行
     **/
    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
        System.out.println("\n beforeCellCreate = 》在单元格创建之前执行");
    }

    /**
     * @date: 2023/7/21 9:43
     * @author: yaobai
     * @description: 单元格创建之后执行
     **/
    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        System.out.println("\n afterCellCreate = 》在单元格创建之后执行");
    }

    /**
     * @date: 2023/7/21 9:44
     * @author: yaobai
     * @description: 在转换数据之后执行
     **/
    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, WriteCellData<?> cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        System.out.println("\n afterCellDataConverted = 》在转换数据之后执行");
    }
}
